package cn.iune.erp.purchase;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.justep.baas.Utils;
import com.justep.baas.data.Row;
import com.justep.baas.data.RowState;
import com.justep.baas.data.Table;
import com.justep.baas.data.Transform;

@Transactional
@Service
public class PurchaseOrderServiceImpl implements IPurchaseOrderService {
	
	private final Logger log = LogManager.getLogger(this);

	@Autowired
	private IPurchaseOrderDao dao;
	@Autowired
	private IPurchaseOrderDetailDao detailDao;
	

	@Override
	public List<PurchaseOrder> getAll(){
		return dao.getAll();
	}
	@Override
	public PurchaseOrder getByID(String fID) {
		return dao.getByID(fID);
	}

	@Transactional
	@Override
	public void delete(String fID, String ucode, String uname, String uid) {
		dao.delete(fID, ucode, uname, uid);
	}

	@Override
	public PurchaseOrder getByNo(String recordNo, String enterpriseNo) {
		return dao.getByNo(recordNo, enterpriseNo);
	}
	
	@Transactional
	@Override
	public JSONObject save(JSONObject object) throws ParseException {
		
		//System.out.println("save.object-->>"+object.toJSONString());
		
		String ucode = object.getString("ucode");
		String uname = object.getString("uname");
		String uid = object.getString("uid");
		
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		//System.out.println("table.getTableName()-->>"+table.getTableName());
		
		JSONObject json = new JSONObject();
		json.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			//System.out.println(javaObject);
			PurchaseOrder obj = JSON.toJavaObject(javaObject, PurchaseOrder.class);
			//System.out.println(obj.getRowState().name());
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj, ucode, uname, uid);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				dao.delete(obj.getfID(), ucode, uname, uid);
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				System.out.println(obj.getfID()+"更新之前的version："+obj.getVersion());
				PurchaseOrder objNew = dao.update(obj, ucode, uname, uid);
				System.out.println(obj.getfID()+"更新之后的version："+objNew.getVersion());
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
			}
		}
		
		json.put("rows", rows);
		
		return json;
	}
	
	@Transactional
	@Override
	public JSONObject saveDetail(JSONObject object) throws ParseException {
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
//		List<ShopCart> list = rowsToList(table.getRows());
		
		//System.out.println(table.getTableName());
		
		JSONObject json = new JSONObject();
		json.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			PurchaseOrderDetail obj = JSON.toJavaObject(javaObject, PurchaseOrderDetail.class);
			if(RowState.NEW.equals(obj.getRowState())){
				detailDao.insert(obj);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				detailDao.delete(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				PurchaseOrderDetail objNew = detailDao.update(obj);
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
			}
		}
		
		json.put("rows", rows);
		
		return json;
	}
	
	@Override
	public JSONObject query(JSONObject data) throws SQLException {
		// TODO Auto-generated method stub
		return dao.query(data);
	}
	
	@Override
	public List<PurchaseOrderDetail> getByMasterID(String fMasterID) {
		return detailDao.getByMasterID(fMasterID);
	}
	
	///////////////////////业务功能///////////////////////////////////////
	
	
	@Transactional
	@Override
	public int confirm(String fID, String ucode, String uname, String uid) {
		PurchaseOrder so = dao.getByID(fID);
		so.setState("confirm");
		so.setResultStatus("审核中");
		dao.update(so, ucode, uname, uid);
		return 0;
	}
	
	@Transactional
	@Override
	public int active(String fID, String ucode, String uname, String uid) {
		PurchaseOrder so = dao.getByID(fID);
		so.setState("active");
		so.setResultStatus("待审核");
		dao.update(so, ucode, uname, uid);
		return 0;
	}
	
	@Transactional
	@Override
	public int close(String fID, String ucode, String uname, String uid) {
		PurchaseOrder so = dao.getByID(fID);
		so.setStatus("close");
		dao.update(so, ucode, uname, uid);
		return 0;
	}
	
	@Transactional
	@Override
	public int open(String fID, String ucode, String uname, String uid) {
		PurchaseOrder so = dao.getByID(fID);
		so.setStatus("open");
		dao.update(so, ucode, uname, uid);
		return 0;
	}
	
	@Transactional
	@Override
	public int agreeIt(String fID, String ucode, String uname, String uid) {
		PurchaseOrder so = dao.getByID(fID);
		//调用入库类，提交单据
		//更新数据库工具入库单的单据状态
		//首先更新从表
		
		so.setAudit("confirm");
		so.setConfirmDate(Utils.getCurrentDate());
		
		so.settUsercode(ucode);
		so.settUsername(uname);
		so.settUserid(uid);
		so.settDatetime(Utils.getCurrentDateTime());
		
		so.setResultStatus("已审核");


		dao.update(so, ucode, uname, uid);
		return 0;
	}
	
	@Transactional
	@Override
	public int unAgree(String fID, String ucode, String uname, String uid) {
		PurchaseOrder so = dao.getByID(fID);
		// TODO Auto-generated method stub
		//调用入库类，提交单据
		//更新数据库工具入库单的单据状态

		so.setAudit("active");
		so.setConfirmDate(null);
		
		so.settUsercode(null);
		so.settUsername(null);
		so.settDatetime(null);
		
		so.setResultStatus("审核中");
		
		dao.update(so, ucode, uname, uid);

		return 0;
	}

	
	/*
	//更新预收款金额
	@Transactional
	@Override
	public int updatePredictAmounting(String stockNo, String enterpriseNo, BigDecimal predictAmount) {
		PurchaseOrder so = dao.getByNo(stockNo, enterpriseNo);
		so.setPredictAmounting(so.getPredictAmounting().add(predictAmount));
		dao.update(so);
		return 0;
	}
	*/

	
	//待审核单据数量
	@Override
	public long getUnAgreeCount(String enterpriseNo) {
		return dao.getUnAgreeCount(enterpriseNo);
	}
	
	
	@Override
	public JSONObject newData(JSONObject data) {
		return dao.create(data);
	}
	
	@Override
	public JSONObject deleteData(JSONObject param) {
		String ucode = param.getString("ucode");
		String uname = param.getString("uname");
		String uid = param.getString("uid");
		
		JSONArray ids = param.getJSONArray("ids");
		for(int i=0;i<ids.size();i++){
			String id = ids.getString(i);
			//这里可以增加是否可删除的判断
			
			//首先删除子表
			List<PurchaseOrderDetail> sods = detailDao.getByMasterID(id);
			for(PurchaseOrderDetail sod:sods){
				detailDao.delete(sod.getfID());
			}

			//然后删除主表
			dao.delete(id, ucode, uname, uid);
		}

		JSONObject data = new JSONObject();
		data.put("ids", ids);
		
		JSONObject json = new JSONObject();
		json.put("code", 0);
		json.put("msg", "success");
		json.put("data", data);
		
		return json;
	}
	
	@Override
	public JSONObject saveData(JSONObject param) {
		// TODO Auto-generated method stub
		JSONObject data;
		try {
			//保存主表
			data = this.save(param);
			
			//保存从表
			JSONArray slaves = param.getJSONArray("slaves");
			JSONObject slaveParam = slaves.getJSONObject(0);
			
			JSONObject slaveData = this.saveDetail(slaveParam);
			
			JSONArray slaveDatas = new JSONArray();
			slaveDatas.add(slaveData);
			data.put("slaves", slaveDatas);
					
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", data);
			
			return json;
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			log.info("开始打印ParseException");
			e.printStackTrace();
			log.info("e.getMessage()-->>"+e.getMessage());
			log.info("完成打印ParseException");
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			
			return json;
		} 
	}
	
	@Override
	public JSONObject queryData(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = dao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	
	@Override
	public JSONObject validData(JSONObject param) {
		// TODO Auto-generated method stub
		return null;
	}

	//新增子表
	@Override
	public JSONObject newDataDetail(JSONObject data) {
		return detailDao.create(data);
	}
	
	//查询子表
	@Override
	public JSONObject queryDataDetail(JSONObject param) {
		// TODO Auto-generated method stub
		try {
			JSONObject jsonTable = detailDao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}
	
	
	
	//更新正在入库数量
	@Transactional
	@Override
	public int updateStoreItemQuantityIng(String fID, BigDecimal itemQuantity) {
		PurchaseOrder so = dao.getByID(fID);
		so.setStoreItemIng(so.getStoreItemIng().add( itemQuantity));
		dao.update(so);
		return 0;
	}
	
	//更新入库数量
	@Transactional
	@Override
	public int updateStoreItemQuantity(String fID, BigDecimal itemQuantity) {
		PurchaseOrder so = dao.getByID(fID);
		so.setStoreItemIng(so.getStoreItemIng().subtract( itemQuantity));
		so.setStoreItemAmount(so.getStoreItemAmount().add(itemQuantity));
		dao.update(so);
		return 0;
	}
	
	
	//更新正在入库数量
	@Transactional
	@Override
	public int updateStoreItemQuantityIng(
			String stockNo
			,String serialNo			
			,String enterpriseNo			
			,BigDecimal itemQuantity 	//入库数量（合格数量）
			,BigDecimal wasterQuantity
			,BigDecimal ullageQuantity
			,BigDecimal arriveQuantityBack
		 	){
		
		BigDecimal arriveQuantity = itemQuantity.add(wasterQuantity).add(ullageQuantity).add(arriveQuantityBack);
		
		PurchaseOrderDetail s = detailDao.getByNo(stockNo, serialNo, enterpriseNo);
		
		
		//新值保留
		s.setStoreItemIng(s.getStoreItemIng().add(arriveQuantity));
		detailDao.update(s);
		
		
		//更新主表 
		int updateResult=this.updateStoreItemQuantityIng(s.getfMasterID(), itemQuantity);
		if (updateResult<0){
			return -1;
		}
		

		return 0;
	}	
	
	//更新入库数量
	@Transactional
	@Override
	public int updateStoreItemQuantity(
			String stockNo
			,String serialNo			
			,String enterpriseNo			
			,BigDecimal itemQuantity
			,BigDecimal wasterQuantity
			,BigDecimal ullageQuantity
			,BigDecimal arriveQuantityBack
			,BigDecimal pieceQuantity
			){
		
		BigDecimal arriveQuantity = itemQuantity.add(wasterQuantity).add(ullageQuantity).add(arriveQuantityBack);
		
		PurchaseOrderDetail s = detailDao.getByNo(stockNo, serialNo, enterpriseNo);
		if(s==null){
			return -1;
		}

		//新值保留
		s.setStoreItemIng(s.getStoreItemIng().subtract(arriveQuantity));
		s.setStoreItemAmount(s.getStoreItemAmount().add(itemQuantity));
		s.setStorePiece(s.getStorePiece().add(pieceQuantity));
		detailDao.update(s);
		
		
		//更新主表 
		int updateResult=this.updateStoreItemQuantity(s.getfMasterID(), itemQuantity);
		if (updateResult<0){
			return -1;
		}
		

		return 0;
	}
	
	//更新退货数量
	@Transactional
	@Override
	public int updateBackItemQuantity(
			String stockNo
			,String serialNo			
			,String enterpriseNo			
			,BigDecimal itemQuantity
			,BigDecimal pieceQuantity
			){
		
//		BigDecimal arriveQuantity = itemQuantity.add(wasterQuantity).add(ullageQuantity).add(arriveQuantityBack);
		
		PurchaseOrderDetail s = detailDao.getByNo(stockNo, serialNo, enterpriseNo);

		//新值保留
		s.setBackItemAmount(s.getBackItemAmount().add(itemQuantity));
		s.setBackPiece(s.getBackPiece().add(pieceQuantity));
		
		//减少已入库数量
		s.setStoreItemAmount(s.getStoreItemAmount().subtract(itemQuantity));
		s.setStorePiece(s.getStorePiece().subtract(pieceQuantity));
		
		detailDao.update(s);

		return 0;
	}
	

	
}
